using ChatBackend.Models;
using SqlSugar;

namespace ChatBackend.Repositories
{
    public class UserRepository : IUserRepository
    {
        private readonly ISqlSugarClient _db;

        public UserRepository(ISqlSugarClient db)
        {
            _db = db;
        }

        public async Task<User?> GetByIdAsync(int id)
        {
            return await _db.Queryable<User>()
                .Where(u => u.Id == id)
                .FirstAsync();
        }

        public async Task<User?> GetByUsernameAsync(string username)
        {
            return await _db.Queryable<User>()
                .Where(u => u.Username == username)
                .FirstAsync();
        }

        public async Task<User?> GetByEmailAsync(string email)
        {
            return await _db.Queryable<User>()
                .Where(u => u.Email == email)
                .FirstAsync();
        }

        public async Task<User?> GetByUsernameOrEmailAsync(string usernameOrEmail)
        {
            return await _db.Queryable<User>()
                .Where(u => u.Username == usernameOrEmail || u.Email == usernameOrEmail)
                .FirstAsync();
        }

        public async Task<List<User>> GetAllAsync()
        {
            return await _db.Queryable<User>().ToListAsync();
        }

        public async Task<List<User>> SearchUsersAsync(string searchTerm)
        {
            return await _db.Queryable<User>()
                .Where(u => u.Username.Contains(searchTerm) ||
                           (u.DisplayName != null && u.DisplayName.Contains(searchTerm)) ||
                           u.Email.Contains(searchTerm))
                .ToListAsync();
        }

        public async Task<User> CreateAsync(User user)
        {
            user.CreatedAt = DateTime.UtcNow;
            user.UpdatedAt = DateTime.UtcNow;
            
            var result = await _db.Insertable(user).ExecuteReturnEntityAsync();
            return result;
        }

        public async Task<User> UpdateAsync(User user)
        {
            user.UpdatedAt = DateTime.UtcNow;
            await _db.Updateable(user).ExecuteCommandAsync();
            return user;
        }

        public async Task<bool> DeleteAsync(int id)
        {
            var result = await _db.Deleteable<User>().Where(u => u.Id == id).ExecuteCommandAsync();
            return result > 0;
        }

        public async Task<bool> ExistsAsync(int id)
        {
            return await _db.Queryable<User>().Where(u => u.Id == id).AnyAsync();
        }

        public async Task<bool> UsernameExistsAsync(string username)
        {
            return await _db.Queryable<User>().Where(u => u.Username == username).AnyAsync();
        }

        public async Task<bool> EmailExistsAsync(string email)
        {
            return await _db.Queryable<User>().Where(u => u.Email == email).AnyAsync();
        }

        public async Task UpdateOnlineStatusAsync(int userId, bool isOnline)
        {
            await _db.Updateable<User>()
                .SetColumns(u => new User { IsOnline = isOnline, UpdatedAt = DateTime.UtcNow })
                .Where(u => u.Id == userId)
                .ExecuteCommandAsync();
        }

        public async Task UpdateLastSeenAsync(int userId, DateTime lastSeen)
        {
            await _db.Updateable<User>()
                .SetColumns(u => new User { LastSeenAt = lastSeen, UpdatedAt = DateTime.UtcNow })
                .Where(u => u.Id == userId)
                .ExecuteCommandAsync();
        }
    }
}
